﻿using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using PMPUtils.DB;
using PMPUtils.Configuration;
using System.Collections;
using PMPUtils.Form;
using CrystalDecisions.Web;

namespace PMPUtils.Report
{
    public class BurndownProgressOperator
    {
        /// <summary>
        /// Return true if burndown progress is already initialized
        /// </summary>
        /// <param name="sprint"></param>
        /// <returns></returns>
        public static bool IsBurndownProgressInitialized(String sprint)
        {
            String strQuery = "select COUNT(id) exist from burndown_progress where sprint = '" + sprint + "'";
            DBOperator dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
            DataTable dtInitialized = dbOperator.Read(strQuery);

            bool isInitialized = false;
            foreach (DataRow row in dtInitialized.Rows)
            {
                if (row["exist"] != DBNull.Value)
                {
                    if (Convert.ToInt32(row["exist"]) >= 1)
                    {
                        isInitialized = true;
                    }
                }
            }

            return isInitialized;
        }

        /// <summary>
        /// Initialize burndown capacity
        /// </summary>
        /// <param name="sprint"></param>
        public static void InitializeBurndownProgress(String sprint)
        {
            String strInsertBurndown = String.Empty;
            String strInsertBurndown1 = String.Empty;
            String strInsertBurndown2 = String.Empty;
            String strInsertBurndown3 = String.Empty;
            String strInsertBurndown4 = String.Empty;
            String strInsertBurndown5 = String.Empty;
            String strInsertBurndown6 = String.Empty;

            if (!IsBurndownProgressInitialized(sprint))
            {

                // Insert burndown with 0.0
                strInsertBurndown = "insert into burndown_progress (sprint, progress";

                for (int i = 1; i <= 10; i++)
                {
                    strInsertBurndown += ", weekday" + i.ToString().PadLeft(2, '0');
                }

                strInsertBurndown += " ) ";

                strInsertBurndown1 += strInsertBurndown;
                strInsertBurndown2 += strInsertBurndown;
                strInsertBurndown3 += strInsertBurndown;
                strInsertBurndown4 += strInsertBurndown;
                strInsertBurndown5 += strInsertBurndown;
                strInsertBurndown6 += strInsertBurndown;

                strInsertBurndown1 += " values ('" + sprint + "', '0Starting'";
                strInsertBurndown2 += " values ('" + sprint + "', '1Analyzing'";
                strInsertBurndown3 += " values ('" + sprint + "', '2Designing'";
                strInsertBurndown4 += " values ('" + sprint + "', '3Implementing'";
                strInsertBurndown5 += " values ('" + sprint + "', '4Final'";
                strInsertBurndown6 += " values ('" + sprint + "', '5Hold'";

                strInsertBurndown = String.Empty; 
                for (int i = 1; i <= 10; i++)
                {
                    strInsertBurndown += ", 0";
                }

                strInsertBurndown += " ) ";

                strInsertBurndown1 += strInsertBurndown;
                strInsertBurndown2 += strInsertBurndown;
                strInsertBurndown3 += strInsertBurndown;
                strInsertBurndown4 += strInsertBurndown;
                strInsertBurndown5 += strInsertBurndown;
                strInsertBurndown6 += strInsertBurndown;
            }

            if (!strInsertBurndown1.Equals(String.Empty))
            {
                DBOperator dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
                dbOperator.Update(strInsertBurndown1);

                dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
                dbOperator.Update(strInsertBurndown2);

                dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
                dbOperator.Update(strInsertBurndown3);

                dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
                dbOperator.Update(strInsertBurndown4);

                dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
                dbOperator.Update(strInsertBurndown5);

                dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
                dbOperator.Update(strInsertBurndown6);
            }
        }

        /// <summary>
        /// Update burndown chart based on the remaining estimations.
        /// </summary>
        /// <param name="sprint"></param>
        public static void UpdateBurndownProgress(String sprint, String progress, String numberOfStories)
        {
            String weekday = SprintOperator.ReadSprintOffsetString(sprint);
            String strUpdate = "update burndown_progress " +
                " set " + weekday + " = " + numberOfStories +
                " where sprint = " + sprint + " and progress = '" + progress + "'";
            DBOperator dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
            dbOperator.Update(strUpdate);
        }

        public static void UpdateBurndown(GridView grvGoals, String sprint)
        {
            // Initialize
            InitializeBurndownProgress(sprint);

            Hashtable storyStatuesCount = new Hashtable();
            storyStatuesCount.Add("5Hold", 0);
            storyStatuesCount.Add("4Final", 0);
            storyStatuesCount.Add("3Implementing", 0);
            storyStatuesCount.Add("2Designing", 0);
            storyStatuesCount.Add("1Analyzing", 0);
            storyStatuesCount.Add("0Starting", 0);

            foreach (GridViewRow row in grvGoals.Rows)
            {
                // 0 or 1 means 0Starting
                // 2 means 1Analyzing
                // 3 means 2Designing
                // 4 means 3Implementing
                // 5 means 4Final
                // Others, 5Hold
                String progress = GridViewOperator.GetCellStringValue(grvGoals, row, "Progress");
                int progressHeader = Convert.ToInt32(progress.Substring(0, 1));

                if (progressHeader >= 6) { progress = "5Hold"; }
                else if (progressHeader >= 4) { progress = "4Final"; }
                else if (progressHeader >= 3) { progress = "3Implementing"; }
                else if (progressHeader >= 2) { progress = "2Designing"; }
                else if (progressHeader >= 1) { progress = "1Analyzing"; }
                else { progress = "0Starting"; }

                if (storyStatuesCount.Contains(progress))
                {
                    int storyCount = Convert.ToInt32(storyStatuesCount[progress]);
                    storyCount++;
                    storyStatuesCount[progress] = storyCount;
                }
                else
                {
                    storyStatuesCount.Add(progress, 1);
                }
            }

            foreach (String key in storyStatuesCount.Keys)
            {
                // Update burndown workload data
                UpdateBurndownProgress(sprint, key, storyStatuesCount[key].ToString());
            }
        }

        public static void RefreshReport(CrystalReportSource reportSource)
        {
            String strQuery = "select * from burndown_progress where sprint = (select top 1 id from sprint where iscompleted <> 1 order by sprint)";

            DBOperator dbOperator = new DBOperator(DBConfigurations.LOCAL_CONNECTION_STRING);
            DataTable dtBurndown = dbOperator.Read(strQuery);

            reportSource.ReportDocument.SetDataSource(dtBurndown);
            reportSource.ReportDocument.SetDatabaseLogon(DBConfigurations.LOCAL_SA, DBConfigurations.LOCAL_PASSWORD);
        }
    }
}
